package io.yx.flx.handler;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.http.Header;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import io.yx.flx.entity.BaseResponse;
import io.yx.flx.entity.ClientInfoEntity;
import io.yx.flx.entity.SignVo;
import io.yx.flx.entity.TokenEntity;
import io.yx.flx.util.SignUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取token
 */
public class TokenHandler implements Handler<RoutingContext> {
    private static final Log log = LogFactory.get();

    @Override
    public void handle(RoutingContext rc) {
        String result = run(rc);
        rc.response().putHeader(Header.CONTENT_TYPE.getValue(), "application/json;charset=UTF-8").end(result);
    }

    public String run(RoutingContext rc) {
        try {
            SignVo signVo = rc.getBodyAsJson().mapTo(SignVo.class);
            Long clientId = signVo.getClientId();
            String sign = signVo.getSign();
            if (clientId == null) {
                return BaseResponse.error("客户端id为空");
            }
            if (StrUtil.isBlank(sign)) {
                return BaseResponse.error("签名不能为空");
            }
            List<Entity> clientList = Db.use().findBy("client_info_entity", "id", clientId);
            if (!clientList.stream().findAny().isPresent()) {
                return BaseResponse.error("未找到此客户端信息");
            }
            Entity entity = clientList.stream().findAny().get();
            ClientInfoEntity clientInfoEntity = BeanUtil.toBean(entity, ClientInfoEntity.class);
            Map<String, String> objectMap = new HashMap<>();
            BeanUtil.copyProperties(signVo, objectMap);
            System.out.println("map:" + objectMap);
            try {
                TimeInterval timer = DateUtil.timer();
                String signResult = SignUtil.generateSignature(objectMap, clientInfoEntity.getSecertKey(), SignUtil.SignType.HMACSHA256);
                long interval = timer.interval();
                log.info("计算签名耗时:{}", interval);
                if (signResult.equals(sign)) {
                    //签名正确，生成临时token记录到数据库
                    TokenEntity tokenEntity = new TokenEntity();
                    tokenEntity.setClientId(signVo.getClientId());
                    tokenEntity.setTimestamp(signVo.getTimestamp());
                    tokenEntity.setExpiresTime(signVo.getExpiresTime());
                    tokenEntity.setUsed(false);
                    String token = RandomUtil.randomString(18);
                    tokenEntity.setToken(token);
                    // 重用计时器
                    TimeInterval restart = timer.restart();
                    int insertResult = Db.use().insert(Entity.create("token_entity").parseBean(tokenEntity, true, true));
                    log.info("新增token结果：{}", insertResult);
                    long saveInterval = restart.interval();
                    log.info("写入数据库用时：{}", saveInterval);

                    //返回此条数据的token
                    return BaseResponse.success(tokenEntity);

                } else {
                    //签名错误
                    return BaseResponse.error("9899", "签名错误");
                }

            } catch (Exception e) {
                log.error("计算签名失败：", e);
                return BaseResponse.error("计算签名失败" + e.getMessage());
            }

        } catch (Exception e) {
            return BaseResponse.error(e.getMessage());
        }
    }

}
